/*
 * File:   global_definitions.h
 * Author: oddi
 *
 * Created on January 25, 2010, 6:55 PM
 */

#ifndef _GLOBAL_DEFINITIONS_H
#define	_GLOBAL_DEFINITIONS_H

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef __WINDOWS__
#define HOMEDIR "C:/es1/savedir"
#else
#define HOMEDIR "/home/oddi/Code/sp1cuda/test"
#endif

#include "omp.h"
#include "cuda.h"
#include "cuda_runtime.h"
#include "cuda_runtime_api.h"
#include "driver_types.h"
#include "driver_functions.h"
#include "device_types.h"

#define VERBOSEOUT stdout
#define MAX_BUF_SIZE 512

#define ERROR -1
#define OK 0
#define X 0
#define Y 1
#define Z 2

#define VX 0
#define VY 1
#define VZ 2


#define NUMOFTHREADSPERBLOCK (512)
#define PARTICLEPOOL (5*(int)pow(2,20))
#define NUMOFTHREADBLOCKS (PARTICLEPOOL/NUMOFTHREADSPERBLOCK)

    /*physical constants*/
#define ELECTRON_MASS (9.109e-28)
#define ELECTRON_CHARGE (-4.8032e-10)
#define LIGHT_SPEED (3e10)
#define E_M (ELECTRON_CHARGE)/(ELECTRON_MASS)
#define BOLTZMAN_CONST (1.6e-12)
#define PI (3.141592654) //should be more precisier?
#define QM   (ELECTRON_CHARGE)/(ELECTRON_MASS)
#define QMC  (ELECTRON_CHARGE)/(ELECTRON_MASS)/(LIGHT_SPEED)
#define ERG_IN_V (1.602e-12)

#define NUMOFCELLS (2048)

#define L (100.0)
#define DL (1.0)
#define CELLSIZE (L/NUMOFCELLS)
#define MINZ  (0)
#define MAXZ (L)
#define CYCLES  (50e3)
#define BEAMSPEED (1e7)


#define TX  (1.0)
#define SIGMA sqrt(BOLTZMAN_CONST * TX / ELECTRON_MASS)
#define E0 (0.05)
#define B0  (25)
#define WCE (QMC*B0)
#define K0  (WCE/SIGMA)
#define NPARTICLES  (30*(int)pow(2,20))
#define NVTRSTEPS (300)

#define DT (-0.05*1./(WCE))

#define PULSEDURATION (100*1e-9)
#define PULSEDELAY (5*1e-9)
#define PULSECENTRE_ZPOS  (L/2)
#define PULSEWIDTH (1)
#define PULSEINCTIME (95*1e-9)
#define PULSEDELTIME (PULSEDURATION - PULSEINCTIME)

    /*common macros*/
#define MAX(a,b) ((a >= b) ? (a) : (b))
#define MIN(a,b) ((a <= b) ? (a) : (b))


    /*used float type*/
    typedef float floatdig;

    typedef struct struct_vector3d {
        floatdig v[3];
    } vector3d;

    typedef floatdig timevar;
    typedef vector3d pos3d;
    typedef vector3d size3d;
    typedef vector3d speed3d;
    typedef vector3d efield3d;
    typedef vector3d bfield3d;

    #define DIM3THREADSPERBLOCK //dim3 threadsperblock(NUMOFTHREADSPERBLOCKX, NUMOFTHREADSPERBLOCKY);
    #define PPOOLSPECIFICATOR NUMOFTHREADBLOCKS,NUMOFTHREADSPERBLOCK

    #define GETPROCPARTICLE(BD, BID, TID) (BD.x*BID.x + TID.x)


#define CUDA_CALL(x) { if((x) != cudaSuccess) { \
    printf("Cuda error at %s:%d\n",__FILE__,__LINE__); \
    exit(EXIT_FAILURE);}}

#define CURAND_CALL(x)  { if((x) != CURAND_STATUS_SUCCESS) { \
    printf("Error at %s:%d\n",__FILE__,__LINE__);\
    exit(EXIT_FAILURE);}}
	
#define LOOPOVERPARTICLES(d_p, h_p, ntocopy, nbunches, action) \
		{for (int i = 0; i < (nbunches); i++) \
            {\
                CUDA_CALL(cudaMemcpy((d_p), (h_p), (ntocopy)*sizeof(particle), cudaMemcpyHostToDevice)); \
                action; \
                CUDA_CALL(cudaMemcpy((h_p), (d_p), (ntocopy)*sizeof(particle), cudaMemcpyDeviceToHost)); \
                (h_p) += (ntocopy); \
            } \
        }

#ifdef	__cplusplus
}
#endif

#endif	/* _GLOBAL_DEFINITIONS_H */

